<template>
  <div class="app-container">
    <!-- 第一部分：页面标题与介绍 -->
    <div class="page-header">
      <h3 class="page-title">ADE Corpus Annotation</h3>
      <p class="page-description">
        <strong>Semi-automated Annotation & Review:</strong> We conduct
        semi-automated annotation and review of Adverse Drug Event (ADE)
        corpora. These annotated corpora serve as a robust knowledge base,
        enhancing Retrieval-Augmented Generation (RAG) models in ADE recognition
        tasks.
      </p>
    </div>

    <!-- 第二部分：标注数据选择 -->
    <el-card class="box-card">
      <template #header>
        <div class="clearfix">
          <span>Select Record</span>
        </div>
      </template>
      <!--选择数据源-->
      <el-form :inline="true" class="demo-form-inline">
        <!--选择需要标注的状态： checked/non-checked/not sure-->
        <el-form-item label="Status">
          <el-select v-model="selectedStatus" placeholder="Select Status" size="mini" clearable>
            <el-option v-for="status in dict.type.status" :key="status.value" :label="status.label"
              :value="status.value" />
          </el-select>
        </el-form-item>

        <!--随机数据集按钮-->
        <el-form-item>
          <el-button type="primary" size="mini" icon="el-icon-search" @click="randomOneEmr" :loading="nexting">
            Next
          </el-button>
        </el-form-item>

        <!--报告案例-->
        <el-form-item>
          <el-button type="info" size="mini" icon="el-icon-position" @click="openSaveCase">Report Case</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!--第三部分：语料标注区域      左侧展示病历文书内容，右侧展示标注结果-->

    <el-card class="box-card">
      <el-row :gutter="20" style="margin-top: 20px">
        <el-col :span="14">
          <!--左侧病历内容展示区域：包括病历内容状态展示，操作按钮等-->
          <el-card shadow="hover">
            <template #header>
              <div>
                <span>
                  Current Record:ID-{{ standard.id }}&nbsp;&nbsp;[{{
                    standard.type
                  }}]&nbsp;&nbsp;&nbsp;&nbsp;
                  <dict-tag style="display: inline" :options="dict.type.status" :value="standard.status" />
                </span>

                <div>
                  <el-button type="text" size="medium" icon="el-icon-printer" @click="printRecord" title="print" />
                  <el-button type="text" size="medium" icon="el-icon-document-copy" @click="copyRecord" title="copy" />
                  <el-button type="text" size="medium" icon="el-icon-edit" @click="handleUpdate" title="edit" />
                </div>
              </div>
            </template>

            <div>
              <span style="
                  margin-left: 10px;
                  font-size: 14px;
                  font-weight: 600;
                  margin-right: 5px;
                ">Date:</span><span style="font-size: 14px; margin-right: 20px">{{ standard.year }}-{{ standard.month
                }}</span>
              <span style="
                  margin-left: 10px;
                  font-size: 14px;
                  font-weight: 600;
                  margin-right: 5px;
                ">Source:</span>
              <span style="font-size: 14px">{{ standard.source }}</span>
            </div>
            <!--带有标注标签的病历文书内容展示-->
            <div v-html="emrContent" class="annotated-text"></div>
          </el-card>
        </el-col>

        <!-- 右侧JSON编辑区 -->
        <el-col :span="10">
          <el-card shadow="hover">
            <template #header>
              <div class="clearfix">
                <span>Annotated results</span>
                <div>
                  <el-button type="text" size="medium" icon="el-icon-refresh" @click="resetJson" title="reset ade" />
                  <el-button type="text" size="medium" icon="el-icon-warning-outline" @click="formatJson"
                    title="format json" />
                  <el-button type="text" size="medium" icon="el-icon-edit-outline" @click="insertTemplate"
                    title="insert template" style="margin-right: 20px" />
                 
                   <!--选择大语言模型---->
                  <el-select v-model="form.llmModel" placeholder="Select LLM" size="mini" clearable
                    style="margin-right: 10px; width: 120px">
                    <el-option v-for="dict in dict.type.llm_model" :key="dict.value" :label="dict.label"
                      :value="dict.value" />
                  </el-select>

                  <!--选择Prompt-->
                    <el-select v-model="form.promptId" placeholder="Select Prompt" size="mini"
                      @change="handlePromptChange" clearable style="margin-right: 10px; width: 120px">
                      <el-option v-for="dict in prompts" :key="dict.id" :label="dict.identifier" :value="dict.id" />
                    </el-select>

                    <el-checkbox v-model="form.afterFilter" style="margin-right: 10px; font-size: 12px;">Filter</el-checkbox>

                  <el-button type="primary" size="mini" icon="el-icon-search" @click="recognizeADE"
                    :loading="recognizing"></el-button>
                </div>
              </div>
            </template>

            <div class="json-editor-container">
              <el-input type="textarea" v-model="jsonText" :rows="19" style="font-size: 13px"
                placeholder="Pls input json data(ades)" @input="validateJson" />

              <div class="json-status mt-2">
                <el-tag :type="jsonValid ? 'success' : 'danger'" effect="plain" size="mini">
                  {{ jsonStatusText }}
                </el-tag>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </el-card>

    <!-- 底部操作区 -->
    <el-footer class="footer-container">
      <el-row type="flex" justify="end">
        <el-button type="warning" class="ml-3" @click="saveRecord('2')" :loading="saving">
          Not Sure
        </el-button>
        <el-button type="primary" class="ml-3" @click="saveRecord('0')" :loading="saving">
          UnChecked
        </el-button>
        <el-button type="success" class="ml-3" @click="saveRecord('1')" :loading="saving">
          Checked
        </el-button>
      </el-row>
    </el-footer>

    <!-- 添加或修改标准数据集对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="80%" append-to-body style="margin-bottom: 5px">
      <el-form ref="form">
        <el-form-item label="Content" prop="content">
          <el-input v-model="standard.content" :rows="14" type="textarea" placeholder="" style="font-size: 15px" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">OK</el-button>
        <el-button @click="cancel">Cancel</el-button>
      </div>
    </el-dialog>

    <!-- 添加或修改Ade Cases对话框 -->
    <el-dialog :title="title" :visible.sync="openCase" width="80%" append-to-body>
      <el-form ref="caseform" :model="caseForm" :rules="rules">
        <el-form-item label="Content" prop="content">
          <el-input v-model="caseForm.content" type="textarea" rows="5" placeholder="Pls input content" />
        </el-form-item>
        <el-form-item label="Ades" prop="ades">
          <el-input v-model="caseForm.ades" type="textarea" rows="5" placeholder="Pls input ades(json format)" />
        </el-form-item>
        <el-form-item label="LLM" prop="llm">
          <el-select v-model="caseForm.llm" placeholder="Select LLM">
            <el-option v-for="dict in dict.type.llm_model" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="PromptType" prop="promptType">
          <el-select v-model="caseForm.promptType" placeholder="Select PromptType">
            <el-option v-for="dict in dict.type.prompt_type" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Case Type" prop="type">
          <el-select v-model="caseForm.type" placeholder="Select Case Type">
            <el-option v-for="dict in dict.type.ade_case_type" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Description" prop="description">
          <el-input v-model="caseForm.description" type="textarea" rows="5" placeholder="Pls input description" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitCaseForm">Confirm</el-button>
        <el-button @click="cancelCaseForm">Cancel</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { addCase } from "@/api/ade/case";
import { recognize } from "@/api/ade/adeRecognition";
import { randomEmr, updateEmr, getEmr } from "@/api/ade/emr";
import { listAllPrompt } from "@/api/ade/prompt";

export default {
  name: "EmrRecordEditor",
  dicts: ["status", "llm_model", "prompt_type", "ade_case_type"],
  data() {
    return {
      // 表单数据
      selectedStatus: "0", //non-checked

      // 所有的Prompt
      prompts: [],
      isRagPrompt: false, // 是否是RAG类型的Prompt
      promptType: "", // 默认Prompt类型
      //ADE请求体
      form: {
        emr: "", // 病历内容
        promptId: "", // Prompt ID
        llmModel: "ernie-3.5-8k", // LLM模型
        afterFilter: true, // 是否启用后处理
        // RAG 模式下的检索配置
        retriveConfig: {
          // 检索配置
          collection: "adeknowledge_repeat_filter", // 知识库集合  adeknowledge_repeat_filter
          chunkType: "mark", // 分块类型
          simScoreThreshold: 0.6, // 相似度阈值
          topN: 5, // 返回的相似文档数量
        },
      },

      // 病历数据
      standard: {
        id: "",
        year: "",
        month: "",
        source: "",
        status: "",
        type: "",
        content: "",
        ades: "", // JSON格式的ADEs数据
      },
      //emr内容
      emrContent: "", //带有标签的EMR内容

      //ADE Case 表单
      caseForm: {
        content: null, // 病历内容
        ades: null, // ADE识别结果
        llm: null, // LLM模型
        promptType: null, // Prompt类型
        type: null, // 案例类型
        description: null, // 案例描述
      },
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      //是否显示ade case 对话框
      openCase: false,
      // 表单校验
      rules: {
        content: [
          {
            required: true,
            message: "Content can not be empty!",
            trigger: "blur",
          },
        ],
        ades: [
          {
            required: true,
            message: "Ades can not be empty!",
            trigger: "blur",
          },
        ],
        llm: [
          {
            required: true,
            message: "LLM can not be empty!",
            trigger: "change",
          },
        ],
        promptType: [
          {
            required: true,
            message: "PromptType can not be empty!",
            trigger: "change",
          },
        ],
        type: [
          {
            required: true,
            message: "Case Type can not be empty!",
            trigger: "change",
          },
        ],
        description: [
          {
            required: true,
            message: "Description can not be empty!",
            trigger: "blur",
          },
        ],
      },

      // JSON数据
      jsonText: "",
      jsonValid: true,
      jsonStatusText: "JSON Format Correct",

      // 状态
      // loading: false,
      nexting: false,
      saving: false,
      recognizing: false,
    };
  },
  computed: {},
  created() {
    // 初始化JSON文本
    this.getAllPrompts();
    this.randomOneEmr();
  },
  methods: {
    //==========================================================ADE识别相关操作========================================================

    // 处理Prompt选择变化
    // 根据当前prompt ID 获取到prompt对象 
    handlePromptChange(vaue) {
      const selectedPrompt = this.prompts.find(prompt => prompt.id === vaue);
      if (selectedPrompt) {
        if (selectedPrompt.type === "RAG") {
          this.isRagPrompt = true; // 如果是RAG类型的Prompt
        } else {
          this.isRagPrompt = false; // 如果不是RAG类型的Prompt
        }
        this.promptType = selectedPrompt.type; // 设置当前Prompt类型
      } else {
        this.isRagPrompt = false; // 如果没有找到对应的Prompt，重置为非RAG类型
        this.promptType = ''; // 重置Prompt类型
        //this.$message.error("Selected prompt not found");
      }
    },
    getAllPrompts() {
      // 获取所有的Prompt
      listAllPrompt().then((response) => {
        this.prompts = response.data;
        // 默认选择一个类型为SAG的作为promptid
        const defaultPrompt = this.prompts.find(prompt => prompt.type === "SAG");
        if (defaultPrompt) {  
          this.form.promptId = defaultPrompt.id; // 设置默认的Prompt ID
          console.log("Default Prompt ID:", this.form.promptId);
          this.isRagPrompt = false; // 默认不是RAG类型
          this.promptType = defaultPrompt.type; // 设置默认的Prompt类型
          this.handlePromptChange(defaultPrompt.id); // 处理Prompt变化
        } else {
          this.$message.warning("No default SAG prompt found, please select manually.");
        }
       
      });
    },
    // 识别ADE
    recognizeADE() {
      this.recognizing = true;
      this.nexting = true;
      this.form.emr = this.standard.content; //获取当前要分析的病程记录
      console.log("Recognize ADE with form:", this.form);
      recognize(this.form)
        .then((response) => {
          this.jsonText = JSON.stringify(response.data.ades, null, 2);
          this.formatJson();
          this.recognizing = false;
          this.nexting = false;
        })
        .catch((error) => {
          console.error("Error recognizing ADE:", error);
          this.$message.error("Failed to recognize ADE");
          this.recognizing = false;
          this.nexting = false;
          this.jsonText = "";
        });
    },

    //==========================================================编辑病例内容========================================================
    cancel() {
      this.open = false;
      this.title = "";
    },
    submitForm() {
      //更新EMR内容
      var data = {
        id: this.standard.id,
        content: this.standard.content,
      };
      updateEmr(data)
        .then((response) => {
          this.$modal.msgSuccess("Edit Successfully");
          this.open = false;
          this.getCurrentEmr();
        })
        .catch((error) => {
          this.$modal.msgError(`Fail: ${error.message}`);
        });
    },
    /** 修改按钮操作 */
    handleUpdate() {
      this.open = true;
      this.title = "Edit";
    },

    //==========================================================重新获取当前EMR========================================================
    getCurrentEmr() {
      this.nexting = true;
      getEmr(this.standard.id)
        .then((response) => {
          if (response.data == null || response.data == undefined) {
            this.$message.warning(
              "No aviliable emr data, please change the source or status!"
            );
            this.nexting = false;
            return;
          }
          this.standard = response.data;

          this.jsonText = this.standard.ades;
          this.formatJson();
          this.nexting = false;
        })
        .catch((error) => {
          this.$message.error(`Fail: ${error.message}`);
          this.nexting = false;
        });
    },
    // 随机病历
    randomOneEmr() {
      this.nexting = true;
      this.emrContent = '';
      this.jsonText = '';
      var data = { status: this.selectedStatus };
      randomEmr(data)
        .then((response) => {
          if (response.data == null || response.data == undefined) {
            this.$message.warning(
              "No aviliable emr data, please change the source or status!"
            );
            this.nexting = false;
            return;
          }
          this.standard = response.data;
          this.jsonText = this.standard.ades;
          //如果没有识别结果 默认自动识别一次。
          if (this.jsonText == null || this.jsonText == undefined) {
            this.recognizeADE();
            //this.jsonText='[]';
          } else{
            this.formatJson();
            this.nexting = false;
           }
        })
        .catch((error) => {
          // this.$message.error("Too fast, please wait a moment!");
          this.nexting = false;
        });
    },

    //=====================================================JSON编辑器相关操作========================================================
    //插入ADE JSON模板
    insertTemplate() {
      try {
        const parsed = JSON.parse(this.jsonText);
        let jo = {};
        for (let i = 0; i < parsed.length; i++) {  //检查每个元素给元素补全
          jo = parsed[i];
          if (jo.drugs == undefined) this.$set(jo, 'drugs', []);
          if (jo.reactions == undefined) this.$set(jo, 'reactions', []);
          if (jo.sentence == undefined) this.$set(jo, 'sentence', '');
        }
        this.jsonText = JSON.stringify(parsed, null, 2);
      } catch (error) {
        //如果标注内容JSON格式不符合  则直接初始化1个
        this.jsonText = '[{"drugs":[],"reactions":[],"sentence":""}]';
        const parsed = JSON.parse(this.jsonText);
        this.jsonText = JSON.stringify(parsed, null, 2);
      }
    },
    // 重置JSON数据  还原JSON数据
    resetJson() {
      //拿到原始的JSON字符串
      this.jsonText = this.standard.ades;
      this.formatJson();
    },
    // 格式化JSON
    formatJson() {
      try {
        const parsed = JSON.parse(this.jsonText);
        this.hightlightJson(parsed);
        this.jsonText = JSON.stringify(parsed, null, 2);
        this.jsonValid = true;
        this.jsonStatusText = "JSON Format Correct!";
      } catch (error) {
        this.jsonValid = false;
        this.jsonStatusText = `Wrong Format: ${error.message}`;
        this.$message.error("JSON Format Wrong，Can not be formatted!");
      }
    },
    hightlightJson(parsed) {
      this.emrContent = this.standard.content; // 初始化格式化的EMR内容    将emrContent中识别到的sentence打上标签 便于展示
      let rep = "";
      for (let i = 0; i < parsed.length; i++) {
        rep = parsed[i].sentence; // 将其他ADE名称用 | 分隔
        if (rep == null || rep == undefined) {
          //如果sentence沒有標注
          for (let j = 0; j < parsed[i].reactions.length; j++) {
            rep = parsed[i].reactions[j];
            this.emrContent = this.emrContent.replaceAll(
              rep,
              '<font color="red">' + rep + "</font>"
            );
          }
        } else {
          this.emrContent = this.emrContent.replaceAll(
            rep,
            '<font color="red">' + rep + "</font>"
          );
        }
      }
    },
    // 验证JSON
    validateJson() {
      let res = this.validateJsonFormat(this.jsonText);
      if (res == 0) {
        //JSON格式解析失败
        this.jsonValid = false;
        this.jsonStatusText = `Wrong Format Json Format.`;
      }
      if (res == 2) {
        //JSOn内容不符合要求
        this.jsonValid = false;
        //JSON格式不符合要求，必须为[{"sentence":"","drugs":[""], "reactions":[""]}]格式
        this.jsonStatusText = `Wrong Json Content,Correct is: [{"sentence":"","drugs":[""], "reactions":[""]}]`;
      }
      if (res == 1) {
        //JSON 格式和内容都正确
        this.jsonValid = true;
        this.jsonStatusText = "JSON Format Correct!";
      }
    },

    //验证JsonText 满足ADE标注需求
    // 0-json解析失败  2-ADE格式不符合    1-正常（JSON格式以及ADE格式都满足）
    validateJsonFormat(jsonText) {
      try {
        const parsedData = JSON.parse(jsonText);

        // 检查是否为数组
        if (!Array.isArray(parsedData)) {
          return 2;
        }

        // 检查数组中的每个对象
        for (const item of parsedData) {
          // 检查对象是否包含所需的属性
          if (
            typeof item !== "object" ||
            item === null ||
            !("sentence" in item) ||
            !("drugs" in item) ||
            !("reactions" in item)
          ) {
            return 2;
          }

          // 检查 sentence 是否为字符串
          if (typeof item.sentence !== "string") {
            return 2;
          }

          // 检查 drugs 是否为数组且包含至少一个字符串
          if (
            !Array.isArray(item.drugs) ||
            // item.drugs.length === 0 ||
            !item.drugs.every((drug) => typeof drug === "string")
          ) {
            return 2;
          }

          // 检查 reactions 是否为数组且包含至少一个字符串
          if (
            !Array.isArray(item.reactions) ||
            item.reactions.length === 0 ||
            !item.reactions.every((reaction) => typeof reaction === "string")
          ) {
            return 2;
          }
        }

        return 1;
      } catch (e) {
        // JSON 解析失败
        return 0;
      }
    },

    //=====================================================ADE 语料审核处理========================================================
    //标记不确定的病历
    saveRecord(cur_status) {
      this.validateJson();
      if (!this.jsonValid) {
        this.$message.error("JSON Format Wrong, please fix it first!");
        return;
      }

      this.saving = true;
      var data = {
        id: this.standard.id,
        status: cur_status,
        ades: this.jsonText,
      };
      // console.log("saveRecord data:", data);
      updateEmr(data)
        .then((response) => {
          this.saving = false;
          this.$message.success("Edit Successfully");
          this.getCurrentEmr();
        })
        .catch((error) => {
          this.saving = false;
          this.$message.error(`Fail: ${error.message}`);
        });
    },

    // 打印病历
    printRecord() {
      window.print();
    },

    // 复制病历
    copyRecord() {
      const textToCopy = this.standard.content;

      navigator.clipboard
        .writeText(textToCopy)
        .then(() => {
          this.$message.success("Copy successful!");
        })
        .catch((err) => {
          this.$message.error("Copy failed: " + err);
          console.error("Copy failed:", err);
        });
    },

    //=============================================新增案例=========================
    // 取消按钮
    cancelCaseForm() {
      this.openCase = false;
      this.resetForm("caseform");
    },
    //打开保存case对话框
    openSaveCase() {
      this.cancelCaseForm();
      this.title = "Save Case";
      this.caseForm.content = this.standard.content;
      this.caseForm.ades = this.jsonText ? this.jsonText : "[]";
      this.caseForm.llm = this.form.llmModel;
      this.caseForm.promptType = this.promptType ? this.promptType : "";
       this.caseForm.source = "Ade Corpus";

      this.openCase = true;
    },
    /** 提交按钮 */
    submitCaseForm() {
      this.$refs["caseform"].validate((valid) => {
        if (valid) {
          addCase(this.caseForm).then((response) => {
            this.$modal.msgSuccess("Report Case Successfully!");
            this.openCase = false;
          });
        }
      });
    },
  },
};
</script>

<style>
.box-card {
  margin-bottom: 10px;
}

.page-header {
  margin-bottom: 20px;
}

.page-title {
  margin-top: 5px;
  font-size: 24px;
  color: #303133;
  margin-bottom: 0px;
  font-weight: bold;
}

.page-description {
  font-size: 16px;
  color: #606266;
  line-height: 1.5;
}

.annotated-text {
  min-height: 380px;
  font-size: 15px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
  line-height: 1.4;
}

/* JSON编辑器样式 */
.json-editor-container {
  position: relative;
}

.json-status {
  text-align: right;
}

/**Standard 详情页面相关样式 */

p.filed-content {
  line-height: 1.6;
  /* 舒适的行高 */
  color: #333;
  /* 深灰色文字，比纯黑更柔和 */
  margin: 0 0 1.2em 0;
  /* 底部外边距 */
  padding: 0.5rem 0.5rem;
  /* 内边距 */
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  /* 柔和渐变背景 */
  border-radius: 8px;
  /* 圆角 */
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  /* 细微阴影 */
  border-left: 4px solid #6c757d;
  /* 左侧装饰性边框（可改主题色） */
  transition: all 0.3s ease;
  /* 悬停动画 */
  flex-grow: 1;
  /* 允许内容段落扩展 */
  white-space: pre-wrap;
  /* 保留空白和换行 */
  font-family: monospace;
  /* 使用等宽字体 */
  font-size: 12px;
}

/* 悬停效果（可选） */
p:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

span.field-label {
  font-size: 12px;
  font-weight: bold;
}
</style>